package cn.edu.gdu.quizpractice.controller.web;

import cn.edu.gdu.quizpractice.entity.ApiResult;
import cn.edu.gdu.quizpractice.entity.ChoiceQuestion;
import cn.edu.gdu.quizpractice.service.ExcelExportService;
import cn.edu.gdu.quizpractice.service.ExcelImportService;
import cn.edu.gdu.quizpractice.service.IChoiceQuestionService;
import cn.edu.gdu.quizpractice.service.IRedisCacheService;
import cn.edu.gdu.quizpractice.common.utils.JwtUtils;
import io.micrometer.core.annotation.Timed;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/web/questions")
@Timed(value = "web/questionController",description = "QuestionController")
@Slf4j
public class QuestionController {
    @Autowired
    private IChoiceQuestionService choiceQuestionService;

    @Autowired
    private ExcelImportService excelImportService;
    
    @Autowired
    private IRedisCacheService redisCacheService;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private ExcelExportService excelExportService;

    @GetMapping("/category/{categoryId}")
    public List<ChoiceQuestion> findByCategory_Id(@PathVariable Integer categoryId) {
        // 定义缓存key
        String cacheKey = "questions:category:" + categoryId;
        
        // 尝试从缓存获取
        Object cachedQuestions = redisCacheService.get(cacheKey);
        if (cachedQuestions != null) {
            log.info("从缓存获取分类{}的问题", categoryId);
            return (List<ChoiceQuestion>) cachedQuestions;
        }
        
        // 缓存未命中，查询数据库
        log.info("缓存未命中，从数据库获取分类{}的问题", categoryId);
        List<ChoiceQuestion> questions = choiceQuestionService.findByCategory_Id(categoryId);
        
        // 将结果存入缓存（设置15分钟过期时间）
        if (questions != null && !questions.isEmpty()) {
            // 创建简化版的问题列表
            List<Map<String, Object>> simplifiedQuestions = questions.stream()
                .map(this::simplifyQuestion)
                .collect(Collectors.toList());
            
            redisCacheService.set(cacheKey, simplifiedQuestions, 15, TimeUnit.MINUTES);
        }
        
        return questions;
    }

    @GetMapping("/difficulty/{difficulty}")
    public List<ChoiceQuestion> findByDifficulty(@PathVariable Integer difficulty) {
        // 定义缓存key
        String cacheKey = "questions:difficulty:" + difficulty;
        
        // 尝试从缓存获取
        Object cachedQuestions = redisCacheService.get(cacheKey);
        if (cachedQuestions != null) {
            log.info("从缓存获取难度{}的问题", difficulty);
            return (List<ChoiceQuestion>) cachedQuestions;
        }
        
        // 缓存未命中，查询数据库
        log.info("缓存未命中，从数据库获取难度{}的问题", difficulty);
        List<ChoiceQuestion> questions = choiceQuestionService.findByDifficulty(difficulty);
        
        // 将结果存入缓存（设置15分钟过期时间）
        if (questions != null && !questions.isEmpty()) {
            // 创建简化版的问题列表
            List<Map<String, Object>> simplifiedQuestions = questions.stream()
                .map(this::simplifyQuestion)
                .collect(Collectors.toList());
            
            redisCacheService.set(cacheKey, simplifiedQuestions, 15, TimeUnit.MINUTES);
        }
        
        return questions;
    }

    @GetMapping("/all")
    public List<ChoiceQuestion> findAll() {
        // 定义缓存key
        String cacheKey = "questions:all";
        
        // 尝试从缓存获取
        Object cachedQuestions = redisCacheService.get(cacheKey);
        if (cachedQuestions != null) {
            log.info("从缓存获取所有问题");
            return (List<ChoiceQuestion>) cachedQuestions;
        }
        
        // 缓存未命中，查询数据库
        log.info("缓存未命中，从数据库获取所有问题");
        List<ChoiceQuestion> questions = choiceQuestionService.findAll();
        
        // 将结果存入缓存（设置10分钟过期时间）
        if (questions != null && !questions.isEmpty()) {
            // 创建简化版的问题列表
            List<Map<String, Object>> simplifiedQuestions = questions.stream()
                .map(this::simplifyQuestion)
                .collect(Collectors.toList());
            
            redisCacheService.set(cacheKey, simplifiedQuestions, 10, TimeUnit.MINUTES);
        }
        
        return questions;
    }

    @PostMapping("/add")
    public ApiResult add(@RequestBody ChoiceQuestion question) {
        // 添加问题
        boolean addQuestion = choiceQuestionService.addQuestion(question);
        if (addQuestion){
            clearAllQuestionCaches(); // 清除所有问题缓存
            log.info("添加问题参数:"+question.getBName());
            return ApiResult.success();
        }else {
            return ApiResult.fail("添加失败");
        }
    }

    @DeleteMapping("/{id}")
    public ApiResult delete(@PathVariable Integer id) {
        // 删除问题
        int deletedQuestion = choiceQuestionService.deleteQuestionById(id);
        if (deletedQuestion > 0){
            clearAllQuestionCaches(); // 清除所有问题缓存
            return ApiResult.success();
        }else {
            return ApiResult.fail("删除失败");
        }
    }

    @PostMapping("/updateQuestion")
    public ApiResult updateQuestion(@RequestBody ChoiceQuestion question) {
        // 更新问题
        choiceQuestionService.updateQuestion(question);

        // 清除所有问题缓存
        clearAllQuestionCaches();

        return ApiResult.success();
    }

    /*@GetMapping("/page")
    public ApiResult<PageBean<ChoiceQuestion>> findByPage(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) String categoryName) {
        // 定义缓存key
        String cacheKey = "questions:page:" + pageNum + ":" + pageSize;
        if (categoryName != null && !categoryName.isEmpty()) {
            cacheKey += ":" + categoryName;
        }
        
        // 尝试从缓存获取
        Object cachedPageBean = redisCacheService.get(cacheKey);
        if (cachedPageBean != null) {
            log.info("从缓存获取分页问题数据: 页码={}, 每页大小={}, 分类={}", pageNum, pageSize, categoryName);
            return ApiResult.success((PageBean<ChoiceQuestion>) cachedPageBean);
        }
        
        // 缓存未命中，查询数据库
        log.info("缓存未命中，从数据库获取分页问题数据: 页码={}, 每页大小={}, 分类={}", pageNum, pageSize, categoryName);
        PageBean<ChoiceQuestion> pb = choiceQuestionService.findByPage(pageNum, pageSize, categoryName);
        
        // 将结果存入缓存（设置5分钟过期时间）
        if (pb != null) {
            // 创建简化版的PageBean
            PageBean<Map<String, Object>> simplifiedPb = new PageBean<>();
            simplifiedPb.setTotal(pb.getTotal());
            
            // 检查PageBean类中是否有这些方法
            if (pb.getTotalPage() != null) {
                simplifiedPb.setTotalPage(pb.getTotalPage());
            }
            if (pb.getCurrentPage() != null) {
                simplifiedPb.setCurrentPage(pb.getCurrentPage());
            }
            if (pb.getPageSize() != null) {
                simplifiedPb.setPageSize(pb.getPageSize());
            }
            
            // 简化问题列表
            if (pb.getRows() != null) {
                List<Map<String, Object>> simplifiedQuestions = pb.getRows().stream()
                    .map(this::simplifyQuestion)
                    .collect(Collectors.toList());
                simplifiedPb.setRows(simplifiedQuestions);
            }
            
            redisCacheService.set(cacheKey, simplifiedPb, 5, TimeUnit.MINUTES);
        }
        
        return ApiResult.success(pb);
    }*/

    @PostMapping("/importExcel")
    public ApiResult<String> importQuestions(@RequestParam("file") MultipartFile file) {
        log.info("收到文件: {}", file.getOriginalFilename());
        // 快速校验文件类型
        if (file.isEmpty()) {
            return ApiResult.fail("文件不能为空");
        }

        String contentType = file.getContentType();
        boolean isExcel = contentType != null && (
                contentType.equals("application/vnd.ms-excel") ||                  // .xls
                        contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") // .xlsx
        );

        if (!isExcel) {
            return ApiResult.fail("仅支持.xls和.xlsx格式文件");
        }

        // 提交异步任务
        CompletableFuture<ApiResult<String>> future = excelImportService.importExcelAsync(file);
        
        // 导入成功后，清除相关缓存
        future.thenAccept(result -> {
            if (result.getCode() == 200) {
                // 清除所有问题相关缓存
                clearAllQuestionCaches();
            }
        });
        
        // 立即返回任务接收响应
        return ApiResult.success("导入任务已提交，请稍后查询结果");
    }
    
    /**
     * 清除所有问题相关缓存
     */
    private void clearAllQuestionCaches() {
        log.info("清除所有问题相关缓存");
        // 清除所有问题列表缓存
        redisCacheService.delete("questions:all");
        
        // 清除分页缓存（可能需要更精细的处理）
        // 这里简单处理，实际可能需要按照pattern删除
        // 如果Redis支持，可以使用keys或scan命令查找匹配的键
        
        // 清除分类和难度相关缓存
        // 实际应用中可能需要更精细的处理
    }
    
    /**
     * 将ChoiceQuestion对象转换为简化版Map
     */
    private Map<String, Object> simplifyQuestion(ChoiceQuestion question) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", question.getCquestionId());
        map.put("content", question.getCqContent());
        map.put("optionA", question.getOptionA());
        map.put("optionB", question.getOptionB());
        map.put("optionC", question.getOptionC());
        map.put("optionD", question.getOptionD());
        map.put("answer", question.getCorrectAnswer());
        map.put("analysis", question.getAnalysis());
        map.put("difficulty", question.getDifficulty());
        map.put("isMultiple", question.getIsMultiple());
        
        // 处理分类信息，避免序列化问题
        if (question.getCategoryName() != null) {
            Map<String, Object> category = new HashMap<>();
            // 检查categoryName是否为字符串或对象
            if (question.getCategoryName() instanceof String) {
                category.put("name", question.getCategoryName());
            } else {
                // 假设categoryName是一个对象，有getId方法
                try {
                    // 使用反射获取id
                    Object id = question.getCategoryName().getClass().getMethod("getId").invoke(question.getCategoryName());
                    category.put("id", id);
                    
                    // 尝试获取name
                    try {
                        Object name = question.getCategoryName().getClass().getMethod("getName").invoke(question.getCategoryName());
                        category.put("name", name);
                    } catch (Exception e) {
                        // 如果没有getName方法，使用toString
                        category.put("name", question.getCategoryName().toString());
                    }
                } catch (Exception e) {
                    // 如果反射失败，直接使用toString
                    category.put("name", question.getCategoryName().toString());
                }
            }
            map.put("category", category);
        }
        
        return map;
    }

    /**
     * 导出题库题目为Excel
     * @param bankName 题库名称
     * @param response HTTP响应对象
     * @throws IOException 如果导出过程中出现IO异常
     */
    @GetMapping("/exportFromDBByConds")
    public void exportFromDBByConds(@RequestParam String bankName, 
                                   HttpServletResponse response) throws IOException {
        // 使用ExcelExportService导出Excel
        excelExportService.exportBankQuestionsToExcel(bankName, response);
    }
} 